# -*- coding: utf-8 -*-
# --------------------------------------------
# RunGAME
# version: 1.3.3
# --------------------------------------------
# Main program file for RunGAME
# --------------------------------------------

print("RunGAME v1.3.3 is running...")
# Importing modules
from files import Files, StartSettings
if Files.ErrorBack or StartSettings.ErrorBack:
    exit()
import func, ConstVars

# Initializing pygame
import pygame
func.ConsoleMess("Import modules successfully")

pygame.init()

# Game class
class GameConsts:
    Info = pygame.display.Info()
if StartSettings.settings["FULLSCREEN"]:
    StartSettings.settings["WIDTH"], StartSettings.settings["HEIGHT"] = GameConsts.Infos.current_w, GameConsts.Infos.current_h

class GameSound:
    def __init__(self, Type: str, way: str):
        self.type = Type
        self.way = way
        self.StartTime = func.time()
        self.NowTime = self.StartTime
        for i in range(len(GameVars.sound_list)):
            if GameVars.sound_list[i].type == self.type:
                GameVars.sound_list[i].StartTime = self.NowTime
                GameVars.sound_list[i].way = self.way
                del self
                return
        GameVars.sound_list.append(self)

    def update(self) -> None:
        self.NowTime = func.time()
        if self.NowTime - self.StartTime > 1:
            GameVars.sound_list.remove(self)
            del self
            return 

class GameVars:
    screen = pygame.display.set_mode((StartSettings.settings["WIDTH"], StartSettings.settings["HEIGHT"]), pygame.RESIZABLE)
    clock = pygame.time.Clock()
    events = pygame.event.get()
    sound_list: list = []
    block_dict: dict = {}
    running: bool = True
    DeltaTime: float = 60
    class ms_key:
        MouseX, MouseY = pygame.mouse.get_pos()
        key_pressed = pygame.key.get_pressed()
    class inputbox:
        inputting: bool = False
        mess: str = ""
    def ScreenResize(isfullscreen):
        for event in pygame.event.get(pygame.VIDEORESIZE):
            size = StartSettings.settings["WIDTH"], StartSettings.settings["HEIGHT"] = event.size[0], event.size[1]
            screen = pygame.display.set_mode((StartSettings.settings["WIDTH"], StartSettings.settings["HEIGHT"]), pygame.RESIZABLE)
        for event in pygame.event.get(pygame.KEYDOWN):
            if event.key == pygame.K_F11:
                if isfullscreen:
                    isfullscreen = False
                    SIZE = StartSettings.settings["WIDTH"], StartSettings.settings["HEIGHT"] = (StartSettings.settings["LASTW"], StartSettings.setting["LASTH"])
                    screen = pygame.display.set_mode((StartSettings.settings["WIDTH"], StartSettings.settings["HEIGHT"]), pygame.RESIZABLE)
                else:
                    isfullscreen = True
                    SIZE = StartSettings.settings["WIDTH"], StartSettings.settings["HEIGHT"] =  pygame.display.list_modes()[0]
                    screen = pygame.display.set_mode(SIZE, pygame.FULLSCREEN)
            pygame.event.post(event)
        return isfullscreen
    def update():
        GameVars.screen.fill(ConstVars.BackColor)
        GameVars.DeltaTime = GameVars.clock.tick(StartSettings.settings["MAXFPS"])
        GameVars.events = pygame.event.get()
        GameVars.ms_key.MouseX, GameVars.ms_key.MouseY = pygame.mouse.get_pos()
        GameVars.ms_key.key_pressed = pygame.key.get_pressed()
        StartSettings.settings["FULLSCREEN"] = GameVars.ScreenResize(StartSettings.settings["FULLSCREEN"])
        for event in GameVars.events:
            if event.type == pygame.QUIT:
                GameVars.running = False
        

# Screen settings for RunGAME frame
pygame.display.set_caption("Minecraft*  Rungame beta v1.3.2")
pygame.display.set_icon(Files.texture.skin.player)
GameVars.screen.fill(ConstVars.BackColor)

# Class for player
class Player(pygame.sprite.Sprite):
    def init(self):
        pygame.sprite.Sprite.__init__(self)
    image = Files.texture.skin.player
    rect = image.get_rect()
    rect.center = (StartSettings.settings["WIDTH"] / 2, StartSettings.settings["HEIGHT"] / 2)
    class move:
        speed = ConstVars.player.speed * GameVars.DeltaTime
        gravity = ConstVars.player.gravity * GameVars.DeltaTime
        strenght = ConstVars.player.strenght * GameVars.DeltaTime
    class ConstInfo:
        ResurPos = ConstVars.player.resurpos
        ResurBool = ConstVars.player.resurbool
        ResurHigh = ConstVars.player.resurhigh
    class nowinfo:
        GameX, GameY = 0, 300
        PosX, PosY = 0, 0
        jumping = False
        suspension = False
    class lastinfo:
        GameX, GameY = 0, 300
        PosX, PosY = 0, 0
        jumping = False
        suspension = False
    
    def TouchBlock() -> bool:
        for i, block in GameVars.block_dict:
            if block.rect.colliderect(Player.rect):
                return True
        return False
    
    def positioning() -> None:
        Player.rect.centerx = StartSettings.settings["WIDTH"] / 2
        Player.rect.centery = StartSettings.settings["HEIGHT"] / 2

    def horizontal(x_speed) -> None:
        Player.nowinfo.GameX += x_speed
        Player.positioning()
        while Player.TouchBlock():
            if x_speed > 0:
                Player.nowinfo.GameX -= 1
            else:
                Player.nowninfo.GameX += 1
            Player.positioning()

    def vertical(y_speed) -> None:
        Player.nowinfo.GameY += y_speed
        Player.positioning()
        while Player.TouchBlock():
            if y_speed > 0:
                Player.nowinfo.GameY -= 1
            else:
                Player.nowinfo.GameY += 1
            Player.positioning()

    def update() -> None:
        # info update
        Player.move.speed = ConstVars.player.speed * GameVars.DeltaTime
        Player.move.gravity = ConstVars.player.gravity * GameVars.DeltaTime
        Player.move.strenght = ConstVars.player.strenght * GameVars.DeltaTime
        Player.nowinfo.PosX, Player.nowinfo.PosY = Player.nowinfo.GameX / 50.0, Player.nowinfo.GameY / 50.0

        # key pressed
        if GameVars.ms_key.key_pressed[pygame.K_a]:
            Player.horizontal(-Player.move.speed)
        if GameVars.ms_key.key_pressed[pygame.K_d]:
            Player.horizontal(Player.move.speed)

class Block(pygame.sprite.Sprite):
    def __init__(self, type: str, x: int, y: int):
        pygame.sprite.Sprite.__init__(self)
        self.image = Files.texture.block.stone
        self.rect = self.image.get_rect()
        self.XPos, self.YPos = (x, y)
        self.RectX = self.YPos * 50
        self.RectY = self.XPos * 50
        self.rect.centerx = self.XPos * 50 - Player.RectX + StartSettings.settings["WIDTH"] / 2
        self.rect.centery = self.YPos * 50 - Player.RectY + StartSettings.settings["HEIGHT"] / 2

    def positioning(self) -> None:
        self.rect.centerx = self.XPos * 50 - player.RollX + settings["WIDTH"] / 2
        self.rect.centery = self.YPos * 50 - player.RollY + settings["HEIGHT"] / 2

    def update(self):
        self.positioning()
        if GameVars.block_dict[(self.XPos, self.YPos)] == 0:
            del GameVars.block_dict[(self.XPos, self.YPos)]
            block_sprites.remove(self)
            self.kill()
            del self


class Indicate(pygame.sprite.Sprite):
    def init(self):
        pygame.sprite.Sprite.__init__(self)
    
    image = Files.texture.other.indicate
    image.set_colorkey("white")
    rect = image.get_rect()
    MousePosX = GameVars.ms_key.MouseX + Player.nowinfo.GameX - StartSettings.settings["WIDTH"] / 2
    MousePosY = GameVars.ms_key.MouseY + Player.nowinfo.GameY - StartSettings.settings["HEIGHT"] / 2
    PosX = func.floor(MousePosX / 50)
    PosY = func.floor(MousePosY / 50)

    def postioning() -> None:
        Indicate.MousePosX = GameVars.ms_key.MouseX + Player.nowinfo.GameX - StartSettings.settings["WIDTH"] / 2 + 25
        Indicate.MousePosY = GameVars.ms_key.MouseY + Player.nowinfo.GameY - StartSettings.settings["HEIGHT"] / 2 + 25
        Indicate.PosX = func.floor(Indicate.MousePosX / 50)
        Indicate.PosY = func.floor(Indicate.MousePosY / 50)
        Indicate.rect.centerx = Indicate.PosX * 50 - Player.nowinfo.GameX + StartSettings.settings["WIDTH"] / 2
        Indicate.rect.centery = Indicate.PosY * 50 - Player.nowinfo.GameY + StartSettings.settings["HEIGHT"] / 2

    def update():
        if not GameVars.inputbox.inputting:
            Indicate.postioning()
        if GameVars.ms_key.MouseX <= 1 or GameVars.ms_key.MouseX >= StartSettings.settings["WIDTH"] - 1 or \
            GameVars.ms_key.MouseY <= 1 or GameVars.ms_key.MouseY >= StartSettings.settings["HEIGHT"] - 1 or GameVars.inputbox.inputting:
            Indicate.image.set_alpha(0)
        else:
            Indicate.image.set_alpha(255)

# Initializing something
Player.init(Player)
Indicate.init(Indicate)

def GetInfo() -> tuple:
    return (
            "Block: %d %d" % (round(Player.nowinfo.PosX), round(Player.nowinfo.PosY)),
            "X: %.2lf  Y: %.2lf" % (Player.nowinfo.PosX, Player.nowinfo.PosY),
            # "Jumping: %d" % (Player.jumping),
            # "Suspenstion: %d" % (Player.suspension),
            # "NowFPS: %d  MaxFPS: %d" % (NowFPS, StartSettings.settings["MAXFPS"]),
            "Speed: %.2lfm/s" % (Player.move.speed),
            "Display: %dx%d" % (StartSettings.settings["WIDTH"], StartSettings.settings["HEIGHT"])
        )

# Main function
def main():
    while GameVars.running:
        GameVars.update()
        
        Player.update()
        Indicate.update()
        GameVars.screen.blit(Player.image, Player.rect.topleft)
        GameVars.screen.blit(Indicate.image, Player.rect.topleft)
        pygame.display.update()
    pygame.quit()

def GameOver():
    StartSettings.save()

func.ConsoleMess("Start game successfully")

if __name__ == "__main__":
    main()
    GameOver()